﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace OnlineShop.Models
{
    public class EFOnlineShopRepository:IOnlineShopRepository
    {
        private OnlineStoreEntities db = new OnlineStoreEntities();

        public OnlineStoreEntities Db
        {
            get { return db; }
            set { db = value; }
        }

        public Product GetDetailProduct(int productId)
        {
            var product = Db.Products.Single(pro => pro.Id == productId && pro.IsDeleted == false);
            return product;
        }

        public void AddProduct(Product product)
        {
            Db.AddToProducts(product);
        }

        public void DeleteProduct(int productId)
        {
            var product = GetDetailProduct(productId);
            if (product != null)
                Db.DeleteObject(product);
        }

        public int CountTotalProduct()
        {
            return Db.Products.Count(pro => pro.IsDeleted.Value == false);
        }

        public int CountProductByCategory(int categoryId)
        {
            return Db.Products.Count(pro => pro.IsDeleted == false && pro.CategoryId.Value == categoryId);
        }

        public IQueryable<Product> FindProductsByName(string name)
        {
            var result = Db.Products.Include("Category")
                                    .Where(pro => pro.IsDeleted == false && pro.Name.Contains(name))
                                    .OrderByDescending(pro => pro.Price);
            return result.AsQueryable();
        }

        public IQueryable<Product> FindProductsByCategory(int categoryId)
        {
            var result = Db.Products.Include("Category")
                                    .Where(pro => pro.IsDeleted == false && pro.CategoryId == categoryId)
                                    .OrderByDescending(pro => pro.Price);
            return result.AsQueryable();
        }

        public IQueryable<Product> GetHotProducts()
        {
            return Db.Products.OrderByDescending(pro => pro.NumView).Take(8);
        }

        public OSUser ValidateUser(string loginName, string password)
        {
            var users = Db.OSUsers.Where(user => user.Email.Equals(loginName.Trim()) && user.Password == password && user.IsActived.Value == true);
            
            if (users != null && users.Count() == 1)
                return users.Single();

            return null; 
        }

        public OSUser FindUserByLoginName(string loginName)
        {
            var users = Db.OSUsers.Where(user => user.Email.Equals(loginName.Trim()) && user.IsActived.Value == true);
            
            if (users != null && users.Count() == 1)
                return users.Single();

            return null;
        }

        public IQueryable<Order> FindOrdersByUser(int userId)
        {
            return Db.Orders.Where(order => order.UserId == userId).AsQueryable();
        }

        public IQueryable<Order> FindOrderByProduct(int productId)
        {
            var orderGroups = Db.OrderDetails.Where(od => od.ProductId == productId).GroupBy(od => od.OrderId);
            var results = new List<Order>();

            foreach (var groupOrder in orderGroups)
            {
                results.Add(groupOrder.ElementAt(0).Order);
            }

            return results.AsQueryable();
            
        }

        public void AddOrder(Order order)
        {
            Db.AddToOrders(order);
        }

        public void DeleteOrder(int orderId)
        {
            var entity = Db.Orders.Single(order => order.Id == orderId);
            Db.DeleteObject(entity);
        }

        public IQueryable<OrderDetail> FindOrderDetailByOrder(int orderId)
        {
            var entity = Db.Orders.Single(order => order.Id == orderId);

            if (entity != null)
                return entity.OrderDetails.AsQueryable();
            return null;
        }

        public void AddOrderDetail(OrderDetail orderDetail)
        {
            Db.AddToOrderDetails(orderDetail);
        }

        public void CommitChanges()
        {
            Db.SaveChanges();
        }
        
        public IQueryable<Category> GetListCategory(bool ActivedOnly=true)
        {
            if (!ActivedOnly)
                return Db.Categories;

            return Db.Categories.Where(c => c.IsActive.Value == ActivedOnly);
        }
        
        public void AddUser(OSUser user)
        {
            Db.AddToOSUsers(user);
        }
    }
}